package org.xshaokuang.loginandemail.tool;

import cn.nukkit.item.Item;
import cn.nukkit.nbt.NBTIO;
import cn.nukkit.nbt.tag.CompoundTag;
import cn.nukkit.nbt.tag.StringTag;
import cn.nukkit.nbt.tag.Tag;

import java.io.IOException;
import java.util.Base64;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;

public class ToolItemBuild {

    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    public static byte[] hexStringToBytes(String hexString) {
        if (hexString == null || "".equals(hexString)) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (byte aSrc : src) {
            int v = aSrc & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    public static Map<String, Object> itemToMap(Item item) {
        LinkedHashMap<String, Object> map = new LinkedHashMap<>();
        if (item == null || item.getId() == 0) {
            return map; // 过滤空气
        }

        try {
            // 序列化基础数据
            map.put("count", item.getCount());
            CompoundTag compoundTag = NBTIO.putItemHelper(item);
            byte[] nbtBytes = NBTIO.write(compoundTag);
            map.put("nbt", Base64.getEncoder().encodeToString(nbtBytes));
            map.put("name", getCustomName(item));

            // 新增 weight 字段（与物品本身无关，仅为配置元数据）
        } catch (IOException e) {
            throw new RuntimeException("物品序列化失败", e);
        }

        return map;
    }

    // 反序列化：Map -> Item（读取 weight 字段，但仅用于外部逻辑）
    public static Item mapToItem(Map<?, ?> map) {
        try {
            if (map.containsKey("nbt")) {
                byte[] nbtBytes = Base64.getDecoder().decode(map.get("nbt").toString());
                CompoundTag compoundTag = NBTIO.read(nbtBytes);
                Item item = NBTIO.getItemHelper(compoundTag);
                if (map.containsKey("count")) {
                    if (map.get("count").toString().contains("~")) {
                        try {
                            String[] count = map.get("count").toString().split("~");
                            item.setCount(Integer.parseInt(count[0]) + new Random().nextInt(Integer.parseInt(count[1]) - Integer.parseInt(count[0]) + 1));
                        } catch (Exception e) {
                            item.setCount(Integer.parseInt(map.get("count").toString()));
                        }
                    } else {
                        item.setCount(Integer.parseInt(map.get("count").toString()));
                    }
                }
                return item;
            } else {
                // 兼容旧版逻辑（可选）
                Item item = Item.fromString(map.get("id").toString());
                if (map.containsKey("count")) {
                    item.setCount(Integer.parseInt(map.get("count").toString()));
                }
                if (map.containsKey("tag")) {
                    byte[] tagBytes = hexStringToBytes(map.get("tag").toString());
                    item.setCompoundTag(Item.parseCompoundTag(tagBytes));
                }
                return item;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String getCustomName(Item item) {
        if (!item.hasCompoundTag()) {
            return item.getName();
        } else {
            CompoundTag tag = item.getNamedTag();
            if (tag.contains("display")) {
                Tag tag1 = tag.get("display");
                if (tag1 instanceof CompoundTag && ((CompoundTag) tag1).contains("Name") && ((CompoundTag) tag1).get("Name") instanceof StringTag) {
                    return ((CompoundTag) tag1).getString("Name");
                }
            }
            return item.getName();
        }
    }
}
